package top.ochiamalu.aioj.util;

import cn.dev33.satoken.stp.StpUtil;
import org.springframework.util.DigestUtils;

import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.ZoneOffset;

/**
 * OAuth State工具类
 *
 * @author ochiamalu
 * @date 2025/03/12
 */
public class OAuthStateUtils {

    private static final long STATE_EXPIRE_TIME = 10 * 60 * 1000;

    /**
     * 生成state
     * 格式：timestamp.md5(sessionId + timestamp + secret)
     */
    public static String generateState(String type) {
        String sessionId = StpUtil.getTokenValue();
        long timestamp = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
        String secret = "your_secret_key";
        
        String content = sessionId + timestamp + secret + type;
        String sign = DigestUtils.md5DigestAsHex(content.getBytes(StandardCharsets.UTF_8));
        
        return timestamp + "." + sign + "." + type;
    }

    /**
     * 验证state
     */
    public static boolean validateState(String state) {
        if (state == null || !state.contains(".")) {
            return false;
        }

        String[] parts = state.split("\\.");
        if (parts.length != 3) {
            return false;
        }

        try {
            // 验证时间戳
            long timestamp = Long.parseLong(parts[0]);
            long now = LocalDateTime.now().toInstant(ZoneOffset.of("+8")).toEpochMilli();
            if (now - timestamp > STATE_EXPIRE_TIME) {
                return false;
            }

            // 验证签名
            String sessionId = StpUtil.getTokenValue();
            String secret = "your_secret_key";
            String content = sessionId + timestamp + secret + parts[2];
            String expectedSign = DigestUtils.md5DigestAsHex(content.getBytes(StandardCharsets.UTF_8));

            return expectedSign.equals(parts[1]);
        } catch (Exception e) {
            return false;
        }
    }

    /**
     * 获取state中的类型
     */
    public static String getStateType(String state) {
        if (state == null || !state.contains(".")) {
            return null;
        }
        String[] parts = state.split("\\.");
        return parts.length == 3 ? parts[2] : null;
    }
} 